home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / toki.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  12KB  |  464 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. #define SPRITE_Y        0
  13. #define SPRITE_TILE        2
  14. #define SPRITE_FLIP_X        2
  15. #define SPRITE_PAL_BANK        4
  16. #define SPRITE_X        6
  17.  
  18. #define XBG1SCROLL_ADJUST(x) (-(x)+0x103)
  19. #define XBG2SCROLL_ADJUST(x) (-(x)+0x101)
  20. #define YBGSCROLL_ADJUST(x) (-(x)-1)
  21.  
  22. unsigned char *toki_foreground_videoram;
  23. unsigned char *toki_background1_videoram;
  24. unsigned char *toki_background2_videoram;
  25. unsigned char *toki_sprites_dataram;
  26. unsigned char *toki_scrollram;
  27. signed char toki_linescroll[256];
  28.  
  29. size_t toki_foreground_videoram_size;
  30. size_t toki_background1_videoram_size;
  31. size_t toki_background2_videoram_size;
  32. size_t toki_sprites_dataram_size;
  33.  
  34. static unsigned char *frg_dirtybuffer;        /* foreground */
  35. static unsigned char *bg1_dirtybuffer;        /* background 1 */
  36. static unsigned char *bg2_dirtybuffer;        /* background 2 */
  37.  
  38. static struct osd_bitmap *bitmap_frg;        /* foreground bitmap */
  39. static struct osd_bitmap *bitmap_bg1;        /* background bitmap 1 */
  40. static struct osd_bitmap *bitmap_bg2;        /* background bitmap 2 */
  41.  
  42. static int bg1_scrollx, bg1_scrolly;
  43. static int bg2_scrollx, bg2_scrolly;
  44.  
  45.  
  46.  
  47. /*************************************
  48.  *
  49.  *        Start/Stop
  50.  *
  51.  *************************************/
  52.  
  53. int toki_vh_start (void)
  54. {
  55.     if ((frg_dirtybuffer = malloc (toki_foreground_videoram_size / 2)) == 0)
  56.     {
  57.         return 1;
  58.     }
  59.     if ((bg1_dirtybuffer = malloc (toki_background1_videoram_size / 2)) == 0)
  60.     {
  61.         free (frg_dirtybuffer);
  62.         return 1;
  63.     }
  64.     if ((bg2_dirtybuffer = malloc (toki_background2_videoram_size / 2)) == 0)
  65.     {
  66.         free (bg1_dirtybuffer);
  67.         free (frg_dirtybuffer);
  68.         return 1;
  69.     }
  70.  
  71.     /* foreground bitmap */
  72.     if ((bitmap_frg = osd_new_bitmap (Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
  73.     {
  74.         free (bg1_dirtybuffer);
  75.         free (bg2_dirtybuffer);
  76.         free (frg_dirtybuffer);
  77.         return 1;
  78.     }
  79.  
  80.     /* background1 bitmap */
  81.     if ((bitmap_bg1 = osd_new_bitmap (Machine->drv->screen_width*2,Machine->drv->screen_height*2,Machine->scrbitmap->depth)) == 0)
  82.     {
  83.         free (bg1_dirtybuffer);
  84.         free (bg2_dirtybuffer);
  85.         free (frg_dirtybuffer);
  86.         osd_free_bitmap (bitmap_frg);
  87.         return 1;
  88.     }
  89.  
  90.     /* background2 bitmap */
  91.     if ((bitmap_bg2 = osd_new_bitmap (Machine->drv->screen_width*2,Machine->drv->screen_height*2,Machine->scrbitmap->depth)) == 0)
  92.     {
  93.         free (bg1_dirtybuffer);
  94.         free (bg2_dirtybuffer);
  95.         free (frg_dirtybuffer);
  96.         osd_free_bitmap (bitmap_bg1);
  97.         osd_free_bitmap (bitmap_frg);
  98.         return 1;
  99.     }
  100.     memset (frg_dirtybuffer,1,toki_foreground_videoram_size / 2);
  101.     memset (bg2_dirtybuffer,1,toki_background1_videoram_size / 2);
  102.     memset (bg1_dirtybuffer,1,toki_background2_videoram_size / 2);
  103.     return 0;
  104.  
  105. }
  106.  
  107. void toki_vh_stop (void)
  108. {
  109.     osd_free_bitmap (bitmap_frg);
  110.     osd_free_bitmap (bitmap_bg1);
  111.     osd_free_bitmap (bitmap_bg2);
  112.     free (bg1_dirtybuffer);
  113.     free (bg2_dirtybuffer);
  114.     free (frg_dirtybuffer);
  115. }
  116.  
  117.  
  118.  
  119. /*************************************
  120.  *
  121.  *        Foreground RAM
  122.  *
  123.  *************************************/
  124.  
  125. WRITE_HANDLER( toki_foreground_videoram_w )
  126. {
  127.    int oldword = READ_WORD (&toki_foreground_videoram[offset]);
  128.    int newword = COMBINE_WORD (oldword, data);
  129.  
  130.    if (oldword != newword)
  131.    {
  132.         WRITE_WORD (&toki_foreground_videoram[offset], data);
  133.         frg_dirtybuffer[offset/2] = 1;
  134.    }
  135. }
  136.  
  137. READ_HANDLER( toki_foreground_videoram_r )
  138. {
  139.    return READ_WORD (&toki_foreground_videoram[offset]);
  140. }
  141.  
  142.  
  143.  
  144. /*************************************
  145.  *
  146.  *        Background 1 RAM
  147.  *
  148.  *************************************/
  149.  
  150. WRITE_HANDLER( toki_background1_videoram_w )
  151. {
  152.    int oldword = READ_WORD (&toki_background1_videoram[offset]);
  153.    int newword = COMBINE_WORD (oldword, data);
  154.  
  155.    if (oldword != newword)
  156.    {
  157.         WRITE_WORD (&toki_background1_videoram[offset], data);
  158.         bg1_dirtybuffer[offset/2] = 1;
  159.    }
  160. }
  161.  
  162. READ_HANDLER( toki_background1_videoram_r )
  163. {
  164.    return READ_WORD (&toki_background1_videoram[offset]);
  165. }
  166.  
  167.  
  168.  
  169. /*************************************
  170.  *
  171.  *        Background 2 RAM
  172.  *
  173.  *************************************/
  174.  
  175. WRITE_HANDLER( toki_background2_videoram_w )
  176. {
  177.    int oldword = READ_WORD (&toki_background2_videoram[offset]);
  178.    int newword = COMBINE_WORD (oldword, data);
  179.  
  180.    if (oldword != newword)
  181.    {
  182.         WRITE_WORD (&toki_background2_videoram[offset], data);
  183.         bg2_dirtybuffer[offset/2] = 1;
  184.    }
  185. }
  186.  
  187. READ_HANDLER( toki_background2_videoram_r )
  188. {
  189.    return READ_WORD (&toki_background2_videoram[offset]);
  190. }
  191.  
  192.  
  193.  
  194. /*************************************
  195.  *
  196.  *        Sprite rendering
  197.  *
  198.  *************************************/
  199.  
  200. void toki_render_sprites (struct osd_bitmap *bitmap)
  201. {
  202.     int SprX,SprY,SprTile,SprFlipX,SprPalette,offs;
  203.     unsigned char *SprRegs;
  204.  
  205.     /* Draw the sprites. 256 sprites in total */
  206.  
  207.     for (offs = 0;offs < toki_sprites_dataram_size;offs += 8)
  208.     {
  209.         SprRegs = &toki_sprites_dataram[offs];
  210.  
  211.         if (READ_WORD (&SprRegs[SPRITE_Y])==0xf100) break;
  212.         if (READ_WORD (&SprRegs[SPRITE_PAL_BANK]))
  213.         {
  214.  
  215.             SprX = READ_WORD (&SprRegs[SPRITE_X]) & 0x1ff;
  216.             if (SprX > 256)
  217.                 SprX -= 512;
  218.  
  219.             SprY = READ_WORD (&SprRegs[SPRITE_Y]) & 0x1ff;
  220.             if (SprY > 256)
  221.               SprY = (512-SprY)+240;
  222.             else
  223.                      SprY = 240-SprY;
  224.  
  225.             SprFlipX   = READ_WORD (&SprRegs[SPRITE_FLIP_X]) & 0x4000;
  226.             SprTile    = READ_WORD (&SprRegs[SPRITE_TILE]) & 0x1fff;
  227.             SprPalette = READ_WORD (&SprRegs[SPRITE_PAL_BANK])>>12;
  228.  
  229.             drawgfx (bitmap,Machine->gfx[1],
  230.                     SprTile,
  231.                     SprPalette,
  232.                     SprFlipX,0,
  233.                     SprX,SprY-1,
  234.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,15);
  235.         }
  236.     }
  237. }
  238.  
  239.  
  240.  
  241. /*************************************
  242.  *
  243.  *        Background rendering
  244.  *
  245.  *************************************/
  246.  
  247. void toki_draw_background1 (struct osd_bitmap *bitmap)
  248. {
  249.     int sx,sy,code,palette,offs;
  250.  
  251.     for (offs = 0;offs < toki_background1_videoram_size / 2;offs++)
  252.     {
  253.         if (bg1_dirtybuffer[offs])
  254.         {
  255.             code = READ_WORD (&toki_background1_videoram[offs*2]);
  256.             palette = code>>12;
  257.             sx = (offs  % 32) << 4;
  258.             sy = (offs >>  5) << 4;
  259.             bg1_dirtybuffer[offs] = 0;
  260.             drawgfx (bitmap,Machine->gfx[2],
  261.                     code & 0xfff,
  262.                     palette,
  263.                     0,0,sx,sy,
  264.                     0,TRANSPARENCY_NONE,0);
  265.         }
  266.     }
  267. }
  268.  
  269.  
  270. void toki_draw_background2 (struct osd_bitmap *bitmap)
  271. {
  272.     int sx,sy,code,palette,offs;
  273.  
  274.     for (offs = 0;offs < toki_background2_videoram_size / 2;offs++)
  275.     {
  276.         if (bg2_dirtybuffer[offs])
  277.         {
  278.             code = READ_WORD (&toki_background2_videoram[offs*2]);
  279.             palette = code>>12;
  280.             sx = (offs  % 32) << 4;
  281.             sy = (offs >>  5) << 4;
  282.             bg2_dirtybuffer[offs] = 0;
  283.             drawgfx (bitmap,Machine->gfx[3],
  284.                     code & 0xfff,
  285.                     palette,
  286.                     0,0,sx,sy,
  287.                     0,TRANSPARENCY_NONE,0);
  288.         }
  289.     }
  290. }
  291.  
  292.  
  293. void toki_draw_foreground (struct osd_bitmap *bitmap)
  294. {
  295.     int sx,sy,code,palette,offs;
  296.  
  297.     for (offs = 0;offs < toki_foreground_videoram_size / 2;offs++)
  298.     {
  299.         if (frg_dirtybuffer[offs])
  300.         {
  301.             code = READ_WORD (&toki_foreground_videoram[offs*2]);
  302.             palette = code>>12;
  303.  
  304.             sx = (offs % 32) << 3;
  305.             sy = (offs >> 5) << 3;
  306.             frg_dirtybuffer[offs] = 0;
  307.             drawgfx (bitmap,Machine->gfx[0],
  308.                     code & 0xfff,
  309.                     palette,
  310.                     0,0,sx,sy,
  311.                     0,TRANSPARENCY_NONE,0);
  312.         }
  313.     }
  314. }
  315.  
  316.  
  317.  
  318. /*************************************
  319.  *
  320.  *        Master update function
  321.  *
  322.  *************************************/
  323.  
  324. void toki_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  325. {
  326.     int title_on;             /* title on screen flag */
  327.  
  328.     bg1_scrolly = YBGSCROLL_ADJUST  (READ_WORD (&toki_scrollram[0]));
  329.     bg1_scrollx = XBG1SCROLL_ADJUST (READ_WORD (&toki_scrollram[2]));
  330.     bg2_scrolly = YBGSCROLL_ADJUST  (READ_WORD (&toki_scrollram[4]));
  331.     bg2_scrollx = XBG2SCROLL_ADJUST (READ_WORD (&toki_scrollram[6]));
  332.  
  333.     /* Palette mapping first */
  334.     {
  335.         unsigned short palette_map[16*4];
  336.         int code, palette, offs;
  337.  
  338.         memset (palette_map, 0, sizeof (palette_map));
  339.  
  340.         for (offs = 0; offs < toki_foreground_videoram_size / 2; offs++)
  341.         {
  342.             /* foreground */
  343.             code = READ_WORD (&toki_foreground_videoram[offs * 2]);
  344.             palette = code >> 12;
  345.             palette_map[16 + palette] |= Machine->gfx[0]->pen_usage[code & 0xfff];
  346.             /* background 1 */
  347.             code = READ_WORD (&toki_background1_videoram[offs * 2]);
  348.             palette = code >> 12;
  349.             palette_map[32 + palette] |= Machine->gfx[2]->pen_usage[code & 0xfff];
  350.             /* background 2 */
  351.             code = READ_WORD (&toki_background2_videoram[offs * 2]);
  352.             palette = code >> 12;
  353.             palette_map[48 + palette] |= Machine->gfx[3]->pen_usage[code & 0xfff];
  354.         }
  355.  
  356.         /* sprites */
  357.         for (offs = 0;offs < toki_sprites_dataram_size;offs += 8)
  358.         {
  359.             unsigned char *data = &toki_sprites_dataram[offs];
  360.  
  361.             if (READ_WORD (&data[SPRITE_Y]) == 0xf100)
  362.                 break;
  363.             palette = READ_WORD (&data[SPRITE_PAL_BANK]);
  364.             if (palette)
  365.             {
  366.                 code = READ_WORD (&data[SPRITE_TILE]) & 0x1fff;
  367.                 palette_map[0 + (palette >> 12)] |= Machine->gfx[1]->pen_usage[code];
  368.             }
  369.         }
  370.  
  371.         /* expand it */
  372.         for (palette = 0; palette < 16 * 4; palette++)
  373.         {
  374.             unsigned short usage = palette_map[palette];
  375.  
  376.             if (usage)
  377.             {
  378.                 int i;
  379.  
  380.                 for (i = 0; i < 15; i++)
  381.                     if (usage & (1 << i))
  382.                         palette_used_colors[palette * 16 + i] = PALETTE_COLOR_USED;
  383.                     else
  384.                         palette_used_colors[palette * 16 + i] = PALETTE_COLOR_UNUSED;
  385.                 palette_used_colors[palette * 16 + 15] = PALETTE_COLOR_TRANSPARENT;
  386.             }
  387.             else
  388.                 memset (&palette_used_colors[palette * 16 + 0], PALETTE_COLOR_UNUSED, 16);
  389.         }
  390.  
  391.         /* recompute */
  392.         if (palette_recalc ())
  393.         {
  394.             memset (frg_dirtybuffer, 1, toki_foreground_videoram_size / 2);
  395.             memset (bg1_dirtybuffer, 1, toki_background1_videoram_size / 2);
  396.             memset (bg2_dirtybuffer, 1, toki_background2_videoram_size / 2);
  397.         }
  398.     }
  399.  
  400.  
  401.     title_on = (READ_WORD (&toki_foreground_videoram[0x710])==0x44) ? 1:0;
  402.  
  403.      toki_draw_foreground (bitmap_frg);
  404.     toki_draw_background1 (bitmap_bg1);
  405.      toki_draw_background2 (bitmap_bg2);
  406.  
  407.     if (title_on)
  408.     {
  409.         int i,scrollx[512];
  410.  
  411.         for (i = 0;i < 256;i++)
  412.             scrollx[i] = bg2_scrollx - toki_linescroll[i];
  413.  
  414.         copyscrollbitmap (bitmap,bitmap_bg1,1,&bg1_scrollx,1,&bg1_scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  415.         if (bg2_scrollx!=-32768)
  416.             copyscrollbitmap (bitmap,bitmap_bg2,512,scrollx,1,&bg2_scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  417.     } else
  418.     {
  419.         copyscrollbitmap (bitmap,bitmap_bg2,1,&bg2_scrollx,1,&bg2_scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  420.         copyscrollbitmap (bitmap,bitmap_bg1,1,&bg1_scrollx,1,&bg1_scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  421.     }
  422.  
  423.     toki_render_sprites (bitmap);
  424.        copybitmap (bitmap,bitmap_frg,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  425. }
  426.  
  427.  
  428.  
  429. static int lastline,lastdata;
  430.  
  431. WRITE_HANDLER( toki_linescroll_w )
  432. {
  433.     if (offset == 2)
  434.     {
  435.         int currline;
  436.  
  437.         currline = cpu_getscanline();
  438.  
  439.         if (currline < lastline)
  440.         {
  441.             while (lastline < 256)
  442.                 toki_linescroll[lastline++] = lastdata;
  443.             lastline = 0;
  444.         }
  445.         while (lastline < currline)
  446.             toki_linescroll[lastline++] = lastdata;
  447.  
  448.         lastdata = data & 0x7f;
  449.     }
  450.     else
  451.     {
  452.         /* this is the sign, it is either 0x00 or 0xff */
  453.         if (data) lastdata |= 0x80;
  454.     }
  455. }
  456.  
  457. int toki_interrupt(void)
  458. {
  459.     while (lastline < 256)
  460.         toki_linescroll[lastline++] = lastdata;
  461.     lastline = 0;
  462.     return 1;  /*Interrupt vector 1*/
  463. }
  464.